<template>
  <div class="canvas-container">
    <canvas
      ref="canvas"
      @mousedown="startDrag"
      @mousemove="drag"
      @mouseup="endDrag"
      @mouseleave="endDrag"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
      @touchcancel="handleTouchEnd"
    />
    <audio ref="successAudio" preload="auto" :src="successSound"></audio>
    <CelebrationParticles ref="celebration" @animationEnd="onAnimationEnd" />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, defineProps, defineEmits } from "vue";
import rough from "roughjs";
import CelebrationParticles from "./CelebrationParticles.vue";
import { Rectangle } from "../game/levels";

const props = defineProps({
  levelConfig: {
    type: Object,
    required: true,
  },
  successSound: {
    type: String,
    default: "/sounds/success.wav",
  },
});

const emit = defineEmits(["levelCompleted"]);

const rc = ref<any>();
const isDragging = ref(false);
const dragOffset = ref({ x: 0, y: 0 });
const draggedRectIndex = ref<number | null>(null);
const canvas = ref<HTMLCanvasElement>();
const isCompleted = ref(false);
const successAudio = ref<HTMLAudioElement>();
const audioInitialized = ref(false);

const celebration = ref<InstanceType<typeof CelebrationParticles>>();

const SNAP_THRESHOLD = 20;
const originalRectBeforeSplit = ref<Rectangle | null>(null);
const pendingSplitIndex = ref<number | null>(null);
const initialDragPos = ref({ x: 0, y: 0 });
const SPLIT_DRAG_THRESHOLD = 15;

const targetBoxes = ref([...props.levelConfig.targetBoxes]);
const rectangles = ref([...props.levelConfig.rectangles]);
const mergedRectangle = ref({ ...props.levelConfig.mergedRectangle });
const hasEmittedCompletion = ref(false);
const originalPositions = ref<Array<{ x: number; y: number }>>([]);

//天平关配置
const balanceAngle = ref(0); // 天平倾斜角度
const targetBalanceAngle = ref(0); // 新增：目标角度
const lastAnimationTime = ref(0); // 记录上次动画时间
const animationRequestId = ref<number | null>(null); // 动画ID

function getEventPosition(e: MouseEvent | TouchEvent): { x: number; y: number } {
  const rect = canvas.value.getBoundingClientRect();
  if (e instanceof MouseEvent) {
    return {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top
    };
  } else {
    // TouchEvent
    return {
      x: e.touches[0].clientX - rect.left,
      y: e.touches[0].clientY - rect.top
    };
  }
}

function isPointInRect(x: number, y: number, rect: Rectangle) {
  return (
    x >= rect.x &&
    x <= rect.x + rect.width &&
    y >= rect.y &&
    y <= rect.y + rect.height
  );
}

function initializeAudio() {
  if (audioInitialized.value || !successAudio.value) return;

  successAudio.value.muted = true;
  successAudio.value
    .play()
    .then(() => {
      successAudio.value.pause();
      successAudio.value.currentTime = 0;
      successAudio.value.muted = false;
      audioInitialized.value = true;
    })
    .catch((e) => {
      console.log("音频初始化失败:", e);
    });
}

function playSuccessSound() {
  if (!successAudio.value || !audioInitialized.value) return;

  successAudio.value.currentTime = 0;
  successAudio.value.play().catch((e) => {
    console.log("音频播放失败:", e);
  });
}

function calculateTargetPositions() {
  if (props.levelConfig.type == null) {
    //基础关
    const canvasWidth = canvas.value.width;
    const canvasHeight = canvas.value.height;

    const totalWidth =
      targetBoxes.value[0].width + targetBoxes.value[1].width + 20;
    const startX = (canvasWidth - totalWidth) / 2;
    const startY = canvasHeight - targetBoxes.value[0].height - 50;

    targetBoxes.value[0].x = startX;
    targetBoxes.value[0].y = startY;
    targetBoxes.value[1].x = startX + targetBoxes.value[0].width + 20;
    targetBoxes.value[1].y = startY;

    const mergedRatio = rectangles.value.reduce(
      (sum, rect) => sum + rect.width / rect.height,
      0
    );

    mergedRectangle.value = {
      ...mergedRectangle.value,
      x: startX,
      y: startY,
      width: totalWidth,
      height: Math.round(totalWidth / mergedRatio),
    };
  } else if (props.levelConfig.type === "balance-scale") {
    // 天平关
    const canvasWidth = canvas.value.width;
    const canvasHeight = canvas.value.height;
    const centerX = canvasWidth / 2;
    const baseY = canvasHeight - 100;

    // 计算左右两侧的矩形数量
    const leftRects = rectangles.value.filter(rect => rect.side === "left").length;
    const rightRects = rectangles.value.filter(rect => rect.side === "right").length;

    // 计算目标框位置
    const spacing = 20;
    const leftStartX = centerX - 180;
    const rightStartX = centerX + 180;
    
    // 更新左侧目标框位置
    for (let i = 0; i < leftRects; i++) {
      targetBoxes.value[i].x = leftStartX - targetBoxes.value[i].width / 2;
      targetBoxes.value[i].y = baseY - 120 + i * (targetBoxes.value[i].height + spacing);
      targetBoxes.value[i].side = "left";
    }
    
    // 更新右侧目标框位置
    for (let i = 0; i < rightRects; i++) {
      const index = leftRects + i;
      targetBoxes.value[index].x = rightStartX - targetBoxes.value[index].width / 2;
      targetBoxes.value[index].y = baseY - 120 + i * (targetBoxes.value[index].height + spacing);
      targetBoxes.value[index].side = "right";
    }

    // 设置原始矩形位置
    const rectSpacing = 20;
    const rectsTotalWidth = rectangles.value.reduce((sum, rect) => sum + rect.width + rectSpacing, 0) - rectSpacing;
    let currentX = (canvasWidth - rectsTotalWidth) / 2;

    rectangles.value.forEach((rect, index) => {
      rect.x = currentX;
      rect.y = rect.y;
      rect.originalX = currentX;
      rect.originalY = rect.y;
      currentX += rect.width + rectSpacing;
    });
  }
}

function drawDivisionLines(ctx: CanvasRenderingContext2D, rect: Rectangle) {
  const ratio = Math.round(rect.width / rect.height);
  
  // 只有当宽高比大于1时才需要绘制分割线
  if (ratio > 1) {
    ctx.strokeStyle = "#333";
    ctx.lineWidth = 1;
    ctx.setLineDash([5, 3]); // 虚线样式
    
    // 计算分割线的数量和位置
    for (let i = 1; i < ratio; i++) {
      const x = rect.x + (rect.width / ratio) * i;
      ctx.beginPath();
      ctx.moveTo(x, rect.y);
      ctx.lineTo(x, rect.y + rect.height);
      ctx.stroke();
    }
    
    ctx.setLineDash([]); // 重置为实线
  }
}

function drawScene() {
  const ctx = canvas.value.getContext("2d");
  ctx.clearRect(0, 0, canvas.value.width, canvas.value.height);

  // 如果是天平关卡，先绘制天平
  if (props.levelConfig.type === "balance-scale") {
    drawBalanceScale();
  }

  if (!(!props.levelConfig?.split && isCompleted.value && props.levelConfig.type == null)){
    targetBoxes.value.forEach((box) => {
      rc.value.rectangle(box.x, box.y, box.width, box.height, {
        fill: "transparent",
        stroke: box.color,
        strokeWidth: 2,
        roughness: 1,
        strokeLineDash: box.occupied ? [] : [10, 5],
        fillStyle: "solid",
      });
    });

    rectangles.value.forEach((rect, index) => {
      // 绘制矩形
      rc.value.rectangle(rect.x, rect.y, rect.width, rect.height, {
        fill: rect.fill,
        stroke: "#333",
        strokeWidth: 2,
        roughness: 1,
      });

      // 绘制分割线
      drawDivisionLines(ctx, rect);

      const centerX = rect.x + rect.width / 2;
      const centerY = rect.y + rect.height / 2;
      const size = Math.min(rect.width, rect.height) * 0.5;
      const number = Math.round(rect.width / rect.height);

      ctx.font = `${size}px Arial`;
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.fillStyle = "black";
      ctx.fillText(number.toString(), centerX, centerY);
    });
  }

  // 只有基础关才显示合并后的矩形
  if (isCompleted.value && props.levelConfig.type == null && !props.levelConfig.split) {
    rc.value.rectangle(
      mergedRectangle.value.x,
      mergedRectangle.value.y,
      mergedRectangle.value.width,
      mergedRectangle.value.height,
      {
        fill: mergedRectangle.value.fill,
        fillStyle: "cross-hatch",
        stroke: "#333",
        strokeWidth: 2,
        roughness: 1,
      }
    );

    // 绘制合并后矩形的分割线
    drawDivisionLines(ctx, mergedRectangle.value);

    const centerX = mergedRectangle.value.x + mergedRectangle.value.width / 2;
    const centerY = mergedRectangle.value.y + mergedRectangle.value.height / 2;
    const size = Math.min(mergedRectangle.value.width, mergedRectangle.value.height) * 0.5;
    const number = Math.round(mergedRectangle.value.width / mergedRectangle.value.height);

    ctx.font = `${size}px Arial`;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillStyle = "black";
    ctx.fillText(number.toString(), centerX, centerY);
  }
}

function checkPlacement(): boolean {
  if (props.levelConfig.type == null) {
    //基础关
    targetBoxes.value.forEach((box) => {
      box.matched = false;
      box.occupied = false;
      box.occupiedBy = null;
      box.color = "#333";
    });

    let allMatched = true;

    rectangles.value.forEach((rect, rectIndex) => {
      rect.targetIndex = null;

      targetBoxes.value.forEach((box, boxIndex) => {
        if (box.occupied) return;

        const rectCenterX = rect.x + rect.width / 2;
        const rectCenterY = rect.y + rect.height / 2;
        const targetCenterX = box.x + box.width / 2;
        const targetCenterY = box.y + box.height / 2;

        const distance = Math.sqrt(
          Math.pow(rectCenterX - targetCenterX, 2) +
            Math.pow(rectCenterY - targetCenterY, 2)
        );

        const isSizeMatched = props.levelConfig?.split
          ? Math.abs(rect.width - box.width) < SNAP_THRESHOLD &&
            Math.abs(rect.height - box.height) < SNAP_THRESHOLD
          : rect.width === box.width && rect.height === box.height;

        if (distance < SNAP_THRESHOLD && isSizeMatched) {
          // 立即锁定位置
          rect.x = box.x;
          rect.y = box.y;
          rect.locked = true;
          rect.targetIndex = boxIndex;

          box.occupied = true;
          box.occupiedBy = rectIndex;
          box.color = "#4CAF50";
        }
      });

      if (!rect.locked) {
        allMatched = false;
      }
    });

    if (allMatched && !isCompleted.value) {
      isCompleted.value = true;
      playSuccessSound();
      celebration.value?.start();
      emit("levelCompleted");
    }

    return allMatched;
  } else if (props.levelConfig.type == "balance-scale") {
    // 天平关
    // 重置所有目标框状态
    targetBoxes.value.forEach((box) => {
      box.matched = false;
      box.occupied = false;
      box.occupiedBy = null;
      box.color = "#333";
    });

    // 检查每个矩形是否放置在正确位置
    rectangles.value.forEach((rect, rectIndex) => {
      rect.targetIndex = null;

      targetBoxes.value.forEach((box, boxIndex) => {
        if (box.occupied) return;

        const rectCenterX = rect.x + rect.width / 2;
        const rectCenterY = rect.y + rect.height / 2;
        const targetCenterX = box.x + box.width / 2;
        const targetCenterY = box.y + box.height / 2;

        const distance = Math.sqrt(
          Math.pow(rectCenterX - targetCenterX, 2) +
          Math.pow(rectCenterY - targetCenterY, 2)
        );

        // 检查是否放置在对应边的目标框
        const isSameSide = rect.side === box.side;
        const isSizeMatched = rect.width === box.width && rect.height === box.height;

        if (distance < SNAP_THRESHOLD && isSizeMatched && isSameSide) {
          rect.x = box.x;
          rect.y = box.y;
          rect.locked = true;
          rect.targetIndex = boxIndex;

          box.occupied = true;
          box.occupiedBy = rectIndex;
          box.color = rect.fill;
        }
      });
    });

    // 实时更新天平角度（不再等待所有矩形放置完毕）
    updateBalanceAnimation();

    // 检查是否所有矩形都已放置
    const allMatched = rectangles.value.every(rect => rect.locked);
    
    // 只有当所有矩形都放置时才检查是否完成关卡
    if (allMatched) {
      const leftSum = rectangles.value
        .filter(rect => rect.side === "left" && rect.targetIndex !== null)
        .reduce((sum, rect) => sum + rect.number, 0);

      const rightSum = rectangles.value
        .filter(rect => rect.side === "right" && rect.targetIndex !== null)
        .reduce((sum, rect) => sum + rect.number, 0);

      const isBalanced = leftSum === rightSum && leftSum === props.levelConfig.requiredSum;

      if (isBalanced) {
        isCompleted.value = true;
        playSuccessSound();
        celebration.value?.start();
        emit("levelCompleted");
        return true;
      }
    }

    return false;
  }
}

function onAnimationEnd() {
  emit("levelCompleted");
}

function checkAutoSnap(x: number, y: number) {
  if (draggedRectIndex.value === null) return { x, y, snapped: false };

  const currentRect = rectangles.value[draggedRectIndex.value];

  for (let i = 0; i < targetBoxes.value.length; i++) {
    const target = targetBoxes.value[i];

    if (target.occupied && target.occupiedBy !== draggedRectIndex.value) {
      continue;
    }

    const widthMatch =
      Math.abs(currentRect.width - target.width) < SNAP_THRESHOLD;
    const heightMatch =
      Math.abs(currentRect.height - target.height) < SNAP_THRESHOLD;

    if (!widthMatch || !heightMatch) continue;

    const rectCenterX = x + currentRect.width / 2;
    const rectCenterY = y + currentRect.height / 2;
    const targetCenterX = target.x + target.width / 2;
    const targetCenterY = target.y + target.height / 2;

    const distance = Math.sqrt(
      Math.pow(rectCenterX - targetCenterX, 2) +
        Math.pow(rectCenterY - targetCenterY, 2)
    );

    if (distance < SNAP_THRESHOLD) {
      return { x: target.x, y: target.y, snapped: true, targetIndex: i };
    }
  }

  return { x, y, snapped: false, targetIndex: null };
}

function startDrag(e: MouseEvent | TouchEvent) {
  if (isCompleted.value) return;

  initializeAudio();

  const { x: mouseX, y: mouseY } = getEventPosition(e);

  for (let i = rectangles.value.length - 1; i >= 0; i--) {
    const r = rectangles.value[i];
    if (isPointInRect(mouseX, mouseY, r)) {
      // 如果矩形已锁定，立即返回
      if (r.locked) {
        return;
      }
      // 如果矩形已经在目标位置，则不允许拖动
      if (r.targetIndex !== null) {
        return;
      }
      if (props.levelConfig.split && r.canSplit) {
        pendingSplitIndex.value = i;
        isDragging.value = true;
        draggedRectIndex.value = i;
        dragOffset.value = {
          x: mouseX - r.x,
          y: mouseY - r.y,
        };
        return;
      }

      isDragging.value = true;
      draggedRectIndex.value = i;
      dragOffset.value = {
        x: mouseX - r.x,
        y: mouseY - r.y,
      };

      if (r.targetIndex !== null) {
        const target = targetBoxes.value[r.targetIndex];
        if (target.occupiedBy === i) {
          target.occupied = false;
          target.occupiedBy = null;
          target.color = "#333";
        }
        r.targetIndex = null;
      }
      break;
    }
  }
}

function handleTouchStart(e: TouchEvent) {
  e.preventDefault();
  startDrag(e);
}

function splitRectangle(index: number, dragX: number) {
  const originalRect = rectangles.value[index];
  originalRectBeforeSplit.value = { ...originalRect };

  // 获取目标框的宽度比例
  const targetWidth1 = targetBoxes.value[0].width;
  const targetWidth2 = targetBoxes.value[1].width;
  const totalTargetWidth = targetWidth1 + targetWidth2;
  const ratio1 = targetWidth1 / totalTargetWidth;
  const ratio2 = targetWidth2 / totalTargetWidth;

  // 根据目标框比例计算拆分后的宽度
  const width1 = originalRect.width * ratio1;
  const width2 = originalRect.width * ratio2;

  const rect1 = {
    ...originalRect,
    x: originalRect.x,
    y: originalRect.y,
    width: width1,
    height: originalRect.height,
    number: Math.round(width1 / originalRect.height),
    canSplit: false,
    originalX: originalRect.originalX,
    originalY: originalRect.originalY,
  };

  const rect2 = {
    ...originalRect,
    x: originalRect.x + width1,
    y: originalRect.y,
    width: width2,
    height: originalRect.height,
    number: Math.round(width2 / originalRect.height),
    canSplit: false,
    originalX: originalRect.originalX + width1,
    originalY: originalRect.originalY,
  };

  rectangles.value.splice(index, 1, rect1, rect2);

  const isDraggingSecond = dragX > width1;
  draggedRectIndex.value = isDraggingSecond ? index + 1 : index;

  const targetRect = rectangles.value[draggedRectIndex.value];
  dragOffset.value = {
    x: dragX - (isDraggingSecond ? width1 : 0),
    y: originalRect.height / 2,
  };

  drawScene();
}

function drag(e: MouseEvent | TouchEvent) {
  if (!isDragging.value || draggedRectIndex.value === null) return;

  const { x: mouseX, y: mouseY } = getEventPosition(e);

  if (pendingSplitIndex.value !== null) {
    const dragDistance = Math.sqrt(
      Math.pow(mouseX - initialDragPos.value.x, 2) +
        Math.pow(mouseY - initialDragPos.value.y, 2)
    );

    if (dragDistance > SPLIT_DRAG_THRESHOLD) {
      splitRectangle(
        pendingSplitIndex.value,
        mouseX - rectangles.value[pendingSplitIndex.value].x
      );
      pendingSplitIndex.value = null;
      return;
    }
  }

  let newX = mouseX - dragOffset.value.x;
  let newY = mouseY - dragOffset.value.y;

  const snapResult = checkAutoSnap(newX, newY);
  newX = snapResult.x;
  newY = snapResult.y;

  const currentRect = rectangles.value[draggedRectIndex.value];
  currentRect.x = Math.max(
    0,
    Math.min(newX, canvas.value.width - currentRect.width)
  );
  currentRect.y = Math.max(
    0,
    Math.min(newY, canvas.value.height - currentRect.height)
  );
  currentRect.targetIndex = snapResult.snapped ? snapResult.targetIndex : null;

  // 立即检查并锁定位置，不等待鼠标抬起
  const wasPlaced = checkPlacement();

  // 如果是天平关卡，更新天平状态
  if (props.levelConfig.type === "balance-scale") {
    updateBalanceAnimation();
  }

  // 如果已放置，立即结束拖动
  if (wasPlaced) {
    endDrag();
  }

  drawScene();
}

function handleTouchMove(e: TouchEvent) {
  e.preventDefault();
  drag(e);
}

function endDrag() {
  if (isDragging.value && draggedRectIndex.value !== null) {
    const rect = rectangles.value[draggedRectIndex.value];

    if (rect.targetIndex === null) {
      if (originalRectBeforeSplit.value) {
        // 处理拆分情况的复位
        animateBackToOriginalPosition(
          draggedRectIndex.value > 0
            ? draggedRectIndex.value - 1
            : draggedRectIndex.value,
          true
        );
      } else {
        // 处理合并/普通情况的复位
        animateBackToOriginalPosition(draggedRectIndex.value);
      }
    }
  }

  isDragging.value = false;
  draggedRectIndex.value = null;
  originalRectBeforeSplit.value = null;
  pendingSplitIndex.value = null;
}

function handleTouchEnd(e: TouchEvent) {
  e.preventDefault();
  endDrag();
}

function animateBackToOriginalPosition(
  index: number,
  isSplitCase: boolean = false
) {
  if (isSplitCase && originalRectBeforeSplit.value) {
    // 处理拆分情况的动画
    const originalRect = { ...originalRectBeforeSplit.value };
    const [rect1, rect2] = [
      rectangles.value[index],
      rectangles.value[index + 1],
    ];

    // 重置状态
    rect1.locked = false;
    rect1.targetIndex = null;
    rect2.locked = false;
    rect2.targetIndex = null;

    // 计算目标位置（基于目标框比例）
    const targetWidth1 = targetBoxes.value[0].width;
    const targetWidth2 = targetBoxes.value[1].width;
    const totalTargetWidth = targetWidth1 + targetWidth2;
    const ratio1 = targetWidth1 / totalTargetWidth;

    const targets = [
      { x: originalRect.x, y: originalRect.y }, // 第一个矩形的目标位置
      { x: originalRect.x + originalRect.width * ratio1, y: originalRect.y }, // 第二个矩形的目标位置
    ];

    const duration = 300;
    const startTime = performance.now();

    const animate = (currentTime: number) => {
      const elapsed = currentTime - startTime;
      const progress = Math.min(elapsed / duration, 1);
      const easeProgress = easeOutQuad(progress);

      // 同时动画两个矩形
      rect1.x = rect1.x + (targets[0].x - rect1.x) * easeProgress;
      rect1.y = rect1.y + (targets[0].y - rect1.y) * easeProgress;
      rect2.x = rect2.x + (targets[1].x - rect2.x) * easeProgress;
      rect2.y = rect2.y + (targets[1].y - rect2.y) * easeProgress;

      drawScene();

      if (progress < 1) {
        requestAnimationFrame(animate);
      } else {
        // 动画完成后恢复原始矩形
        rectangles.value.splice(index, 2, { ...originalRect });
        drawScene();
      }
    };

    requestAnimationFrame(animate);
  } else {
    // 原有普通矩形的动画逻辑
    const rect = rectangles.value[index];

    // 重置状态
    rect.locked = false;
    rect.targetIndex = null;

    const targetX = rect.originalX;
    const targetY = rect.originalY;
    const startX = rect.x;
    const startY = rect.y;

    const duration = 300;
    const startTime = performance.now();

    const animate = (currentTime: number) => {
      const elapsed = currentTime - startTime;
      const progress = Math.min(elapsed / duration, 1);
      const easeProgress = easeOutQuad(progress);

      rect.x = startX + (targetX - startX) * easeProgress;
      rect.y = startY + (targetY - startY) * easeProgress;

      drawScene();

      if (progress < 1) {
        requestAnimationFrame(animate);
      }
    };

    requestAnimationFrame(animate);
  }
}

function easeOutQuad(t: number): number {
  return t * (2 - t);
}

function resetLevel() {
  if (animationRequestId.value) {
    cancelAnimationFrame(animationRequestId.value);
    animationRequestId.value = null;
  }
  
  // 重置角度
  balanceAngle.value = 0;
  targetBalanceAngle.value = 0;
  
  isCompleted.value = false;
  hasEmittedCompletion.value = false;

  rectangles.value = rectangles.value.map((rect) => ({
    ...rect,
    x: rect.originalX,
    y: rect.originalY,
    targetIndex: null,
    locked: false,
  }));
  targetBoxes.value = targetBoxes.value.map((box) => ({
    ...box,
    matched: false,
    occupied: false,
    occupiedBy: null,
    color: "#333",
  }));
  mergedRectangle.value = { ...props.levelConfig.mergedRectangle };

  isDragging.value = false;
  draggedRectIndex.value = null;
  originalRectBeforeSplit.value = null;
  pendingSplitIndex.value = null;

  drawScene();
}

//天平关绘制
function drawBalanceScale() {
  const ctx = canvas.value.getContext("2d");
  const centerX = canvas.value.width / 2;
  const baseY = canvas.value.height - 100;
  const angleRad = (balanceAngle.value * Math.PI) / 180;
  
  // Increased scale factors
  const beamLength = 500; // Increased from 400 (250 on each side)
  const pillarHeight = 200; // Increased from 150
  const baseHeight = 40; // Increased from 30
  const hookDistance = 230; // Increased from 180 (distance from center)

  // 保存画布状态
  ctx.save();

  // 1. 绘制底座和支柱（不受倾斜影响）
  ctx.fillStyle = "#795548";
  ctx.fillRect(centerX - 20, baseY, 40, baseHeight); // Wider base
  ctx.fillStyle = "#607D8B";
  ctx.fillRect(centerX - 8, baseY - pillarHeight, 16, pillarHeight); // Thicker pillar

  // 2. 绘制倾斜的横梁
  ctx.translate(centerX, baseY - pillarHeight);
  ctx.rotate(angleRad);
  ctx.fillStyle = "#9E9E9E";
  ctx.fillRect(-beamLength/2, -8, beamLength, 16); // Longer and thicker beam
  ctx.setTransform(1, 0, 0, 1, 0, 0);

  // 3. 计算悬挂点物理位置
  const leftHookX = centerX - hookDistance + Math.sin(angleRad) * 40;
  const leftHookY = baseY - pillarHeight - Math.cos(angleRad) * 40;
  const rightHookX = centerX + hookDistance + Math.sin(angleRad) * 40;
  const rightHookY = baseY - pillarHeight - Math.cos(angleRad) * 40;

  // 4. 绘制悬挂线（带自然摆动效果）
  ctx.strokeStyle = "#212121";
  ctx.lineWidth = 3; // Thicker lines
  ctx.beginPath();
  
  // 左侧悬挂线（从横梁到第一个左侧目标框）
  const leftTargetIndex = 0;
  ctx.moveTo(leftHookX, leftHookY);
  ctx.lineTo(
    targetBoxes.value[leftTargetIndex].x + targetBoxes.value[leftTargetIndex].width/2 + Math.sin(angleRad) * 15,
    targetBoxes.value[leftTargetIndex].y + Math.abs(Math.sin(angleRad)) * 20
  );
  
  // 右侧悬挂线（从横梁到第一个右侧目标框）
  const rightTargetIndex = targetBoxes.value.findIndex(box => box.side === "right");
  if (rightTargetIndex !== -1) {
    ctx.moveTo(rightHookX, rightHookY);
    ctx.lineTo(
      targetBoxes.value[rightTargetIndex].x + targetBoxes.value[rightTargetIndex].width/2 + Math.sin(angleRad) * 15,
      targetBoxes.value[rightTargetIndex].y + Math.abs(Math.sin(angleRad)) * 20
    );
  }
  
  ctx.stroke();

  // 5. 绘制目标框（随悬挂线自然摆动）
  targetBoxes.value.forEach((box, index) => {
    const isLeft = box.side === "left";
    const baseX = isLeft ? centerX - hookDistance : centerX + hookDistance;
    const swingFactor = isLeft ? -1 : 1;
    
    // 计算垂直位置（考虑上下排列）
    const verticalOffset = index % 2 === 0 ? 0 : box.height + 20;
    
    // 计算目标框位置（随角度摆动）
    const boxX = baseX - box.width/2 + Math.sin(angleRad) * swingFactor * 25;
    const boxY = baseY - 150 + verticalOffset + Math.abs(Math.sin(angleRad)) * 40;
    
    // 更新目标框实际位置（用于碰撞检测）
    box.x = boxX;
    box.y = boxY;
    
    rc.value.rectangle(
      boxX, 
      boxY, 
      box.width, 
      box.height, 
      {
        fill: "transparent",
        stroke: box.color,
        strokeWidth: 2,
        roughness: 1,
        strokeLineDash: box.occupied ? [] : [10, 5],
        fillStyle: "solid",
      }
    );
  });

  ctx.restore();
}
//天平动效
function updateBalanceAnimation() {
  if (props.levelConfig.type !== "balance-scale") return;

  // 只计算已锁定（已放置）的矩形
  const leftSum = rectangles.value
    .filter(rect => rect.side === "left" && rect.locked)
    .reduce((sum, rect) => sum + rect.number, 0);

  const rightSum = rectangles.value
    .filter(rect => rect.side === "right" && rect.locked)
    .reduce((sum, rect) => sum + rect.number, 0);

  // 计算角度差（更平滑的响应）
  const diff = rightSum - leftSum;
  targetBalanceAngle.value = diff === 0 ? 0 : 
    Math.min(Math.max(diff * 1.5, -15), 15);

  // 启动/继续动画
  if (!animationRequestId.value) {
    lastAnimationTime.value = performance.now();
    animateBalance();
  }
}

function animateBalance() {
  const now = performance.now();
  const deltaTime = Math.min(now - lastAnimationTime.value, 50); // 限制最大deltaTime
  lastAnimationTime.value = now;

  // 使用缓动函数实现更平滑的动画
  const angleDiff = targetBalanceAngle.value - balanceAngle.value;
  const direction = angleDiff > 0 ? 1 : -1;
  const easeFactor = 0.1 + Math.min(Math.abs(angleDiff)/30 * 0.9, 0.9);
  
  if (Math.abs(angleDiff) > 0.05) {
    balanceAngle.value += angleDiff * easeFactor * (deltaTime / 16);
    drawScene();
    animationRequestId.value = requestAnimationFrame(animateBalance);
  } else {
    balanceAngle.value = targetBalanceAngle.value;
    animationRequestId.value = null;
    drawScene(); // 确保最终状态绘制
  }
}

onMounted(() => {
  canvas.value.width = canvas.value.offsetWidth;
  canvas.value.height = canvas.value.offsetHeight;
  rc.value = rough.canvas(canvas.value);

  originalPositions.value = rectangles.value.map((rect) => ({
    x: rect.x,
    y: rect.y,
  }));

  calculateTargetPositions();
  drawScene();

  if (props.levelConfig.type === "balance-scale") {
    updateBalanceAnimation();
  }

  window.addEventListener("resize", () => {
    canvas.value.width = canvas.value.offsetWidth;
    canvas.value.height = canvas.value.offsetHeight;
    calculateTargetPositions();
    drawScene();
  });
});

defineExpose({
  resetLevel,
});
</script>

<style scoped>
.canvas-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  touch-action: none; /* 防止触摸事件的默认行为 */
}

canvas {
  display: block;
  width: 100%;
  height: 100%;
  background-color: #f5f5dc;
  cursor: grab;
}

canvas:active {
  cursor: grabbing;
}

audio {
  display: none;
}
</style>